package com.ugold.common.util.validate;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;

/**
 * 数据校验工具类
 * 
 * @author dingjian
 *
 */
public class JSR303Util {
	private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

	/**
	 * JSR303校验
	 * 
	 * @author dingjian
	 * @param object
	 *            需要校验的对象
	 * @param withFiledName
	 *            错误信息是否携带字段名称
	 * @return
	 */
	public static synchronized ValidateResult validate(Object object, boolean withFiledName) {
		if (object == null) {
			throw new NullPointerException("被校验对象不能为NULL");
		}
		ValidateResult result = ValidateResult.failure();
		Set<ConstraintViolation<Object>> validResult = validator.validate(object);
		if (validResult != null && validResult.size() > 0) {
			for (Iterator<ConstraintViolation<Object>> iterator = validResult.iterator(); iterator.hasNext();) {
				while (iterator.hasNext()) {
					ConstraintViolation<Object> constraintViolation = iterator.next();
					if (withFiledName) {
						result.addMessage(
								constraintViolation.getPropertyPath().toString() + constraintViolation.getMessage());
					} else {
						result.addMessage(constraintViolation.getMessage());
					}
				}
			}
		}
		// 无错误信息设置为校验通过
		if (result.hasNoMessages()) {
			result.setPass(true);
		}
		return result;
	}

	/**
	 * 校验Facade调用入参校验
	 * 
	 * @author dingjian
	 * @date 2018年9月28日
	 * @param target
	 *            目标对象
	 * @param method
	 *            被执行的方法
	 * @param args
	 *            方法入参
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public static ValidateResult validateFacadeParamters(Object target, Method method, Object[] args)
			throws NoSuchMethodException, SecurityException {
		if (target == null || method == null || args == null || target.getClass() == Object.class) {
			return null;
		}

		Class<? extends Object> targetClz = target.getClass();
		Class<?>[] interfaces = targetClz.getInterfaces();
		if (interfaces == null || interfaces.length == 0) {
			// 无父接口
			return null;
		}
		for (Class<?> tmpClz : interfaces) {
			if (tmpClz == null) {
				continue;
			}
			// 当前实现的接口的方法
			Method interfaceMethod = tmpClz.getMethod(method.getName(), method.getParameterTypes());
			if (interfaceMethod == null) {
				continue;
			}

			// 当前实现的接口的方法的形参的注解
			Annotation[][] paramAnnotations = interfaceMethod.getParameterAnnotations();
			if (paramAnnotations == null || paramAnnotations.length == 0) {
				continue;
			}
			for (int i = 0; i < paramAnnotations.length; i++) {
				for (int j = 0; j < paramAnnotations[i].length; j++) {
					Annotation annotation = paramAnnotations[i][j];
					if (annotation == null || annotation.annotationType() != Valid.class) {
						continue;
					}
					ValidateResult validateResult = JSR303Util.validate(args[i], false);
					if (!validateResult.isPass()) {
						return validateResult;
					}

				}
			}
		}
		return null;
	}
}
